<?php

/**
 * SmartPHP framework
 *
 * @name SmartPHP framework
 * @package SmartPHP
 * @author 费尔 <admin@smartphp.cn>
 * @version 1.0 Beta
 * @link http://www.smartphp.cn
 * @copyright smartphp.cn
 * @license <a href="http://www.smartphp.cn">smartphp</a>
 */

namespace Driver\Cache;

use \Base\{
    File as F,
    Config
};

/**
 * 文件类型缓存类
 */
class File {

    private $options;

    /**
     * 架构函数
     *
     * @access public
     */
    public function __construct($options = []) {
        if (!empty($options))
            $this->options = $options;
        $this->options['path'] = $options['temp'] ?? Config::get('cache.path');
        $this->options['prefix'] = $options['prefix'] ?? Config::get('cache.prefix');
        $this->options['expire'] = $options['expire'] ?? Config::get('cache.expire');
        $this->options['path'] = rtrim($this->options['path'], '\\/') . DS;
    }

    /**
     * 读取缓存
     *
     * @access public
     * @param string $name 缓存变量名
     * @return mixed
     */
    public function get($name) {
        $filename = $this->filename($name);
        if (!is_file($filename))
            return false;
        $content = F::read($filename);
        if (false !== $content) {
            $expire = (int) substr($content, 8, 12);
            if ($expire != 0 && time() > filemtime($filename) + $expire) {
                unlink($filename);
                return false;
            }
            if (Config::get('cache.check')) {
                $check = substr($content, 20, 32);
                $content = substr($content, 52, - 3);
                if ($check != md5($content))
                    return false;
            } else
                $content = substr($content, 20, - 3);
            if (Config::get('cache.compress') && function_exists('gzcompress'))
                $content = gzuncompress($content);
            return unserialize($content);
        } else
            return false;
    }

    /**
     * 写入缓存
     *
     * @access public
     * @param string $name 缓存变量名
     * @param mixed $value 存储数据
     * @param int $expire 有效时间 0为永久
     * @return boolean
     */
    public function set($name, $value, $expire = null) {
        if (is_null($expire))
            $expire = $this->options['expire'];
        $filename = $this->filename($name);
        $data = serialize($value);
        if (Config::get('cache.compress') && function_exists('gzcompress'))
            $data = gzcompress($data, 3);
        $check = Config::get('cache.check') ? md5($data) : '';
        $data = "<?php\n//" . sprintf('%012d', $expire) . $check . $data . "\n?>";
        return F::write($filename, $data) ? true : false;
    }

    /**
     * 删除缓存
     *
     * @access public
     * @param string $name 缓存变量名
     * @return boolean
     */
    public function rm($name) {
        return F::remove($this->filename($name));
    }

    /**
     * 清除缓存
     *
     * @access public
     * @param string $name 缓存变量名
     * @return boolean
     */
    public function clear() {
        return F::emptyDir($this->options['path']);
    }

    /**
     * 取得变量的存储文件名
     *
     * @access private
     * @param string $name 缓存变量名
     * @return string
     */
    private function filename($name) {
        $name = md5(Config::get('authkey') . $name);
        if (Config::get('cache.subdir')) {
            $dir = '';
            for ($i = 0; $i < Config::get('cache.level'); $i ++)
                $dir .= $name{$i} . DS;
            $filename = $dir . $this->options['prefix'] . $name . '.php';
        } else
            $filename = $this->options['prefix'] . $name . '.php';
        return $this->options['path'] . $filename;
    }

}
